#!/usr/bin/env python3
# -*- coding=utf-8 -*-
# 本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
# 教主QQ:605658506
# 亁颐堂官网www.qytang.com
# 教主技术进化论拓展你的技术新边疆
# https://ke.qq.com/course/271956?tuin=24199d8a

import re
import hashlib
from qyt_devnet_0_ssh import ssh_singlecmd, ssh_multicmd, ssh_multicmd_asa
from datetime import datetime
import django
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DevNet2019.settings')
django.setup()
from devnet.models import Deviceconfig, DeviceconfigDir, Devicedb

configdir = DeviceconfigDir.objects.get(id=1).dir_name


def get_md5_config():
    for device in Devicedb.objects.all():
        if device.type.type_name == 'IOS Router':  # 如果设备是路由器
            # 获取设备show run
            try:
                run_config_raw = ssh_singlecmd(device.ip, device.ssh_username, device.ssh_password, 'show run')
                list_run_config = run_config_raw.split('\n')
            except Exception:
                continue
            location = 0
            host_location = 0  # 用来找到hostname出现的位置
            for i in list_run_config:
                if re.match('.*hostname .*', i):
                    host_location = location  # 定位hostname所在位置
                else:
                    location += 1
            list_run_config = list_run_config[host_location:]  # 截取hostname开始往后的部分
            run_config = '\n'.join(list_run_config)  # 再次还原为字串形式的配置

            # 计算获取配置的MD5值
            m = hashlib.md5()
            m.update(run_config.encode())
            md5_value = m.hexdigest()

        elif device.type.type_name == 'Nexus Switch':  # 如果设备是交换机
            # 获取设备show run
            try:
                run_config_raw = ssh_singlecmd(device.ip, device.ssh_username, device.ssh_password, 'show run')
                list_run_config = run_config_raw.split('\n')
            except Exception:
                continue

            location = 0
            host_location = 0  # 用来找到hostname出现的位置
            for i in list_run_config:
                if re.match('.*hostname .*', i):
                    host_location = location  # 定位hostname所在位置
                else:
                    location += 1
            list_run_config = list_run_config[host_location:]  # 截取hostname开始往后的部分
            run_config = '\n'.join(list_run_config)  # 再次还原为字串形式的配置

            # 计算获取配置的MD5值
            m = hashlib.md5()
            m.update(run_config.encode())
            md5_value = m.hexdigest()

        elif device.type.type_name == 'ASA Firewall':  # 如果设备是ASA
            # 获取设备show run, 注意获取ASA配置的方法不一样
            try:
                run_config_raw = ssh_multicmd_asa(device.ip, device.ssh_username, device.ssh_password, ['enable', device.enable_password, 'terminal pager 0', 'more system:running-config'])
                list_run_config = run_config_raw.split('\n')
            except Exception:
                continue
            location = 0
            host_location = 0  # 用来找到hostname出现的位置
            for i in list_run_config:
                if re.match('^hostname .*', i):  # 注意匹配hostname的方法不一样,因为配置中会多次出现hostname
                    host_location = location  # 定位hostname所在位置
                else:
                    location += 1
            list_run_config = list_run_config[host_location:-4]  # 截取hostname开始往后的部分, 去除最后一些无用部分
            run_config = '\n'.join(list_run_config)  # 再次还原为字串形式的配置

            # 计算获取配置的MD5值
            m = hashlib.md5()
            m.update(run_config.encode())
            md5_value = m.hexdigest()

        try:
            last_config_backup = Deviceconfig.objects.filter(device=device).order_by('-id')[0]
            if last_config_backup.hash == md5_value:  # 如果本次配置的MD5值,与上一次备份配置的MD5值相同!略过此次操作
                continue

        except IndexError:
            pass
        config_filename = device.name + '_' + datetime.now().strftime('%Y-%m-%d-%H-%M') + '_' + md5_value + '.txt'
        file = open(configdir + config_filename, 'w')
        file.write(run_config)
        file.close()
        d = Deviceconfig(device=device,
                         hash=md5_value,
                         config_filename=config_filename)
        d.save()


if __name__ == '__main__':
    get_md5_config()